﻿using System.Collections.Concurrent;
using System.Linq;
using System.Net;

namespace LaoLuo.Net
{
    /// <summary>
    /// 
    /// </summary>
    public class IPHostChecker
    {
        private static readonly ConcurrentDictionary<CheckInfo, bool> ResultCache = new ConcurrentDictionary<CheckInfo, bool>();

        /// <summary>
        /// get a bool value indicates whether <see cref="ip"/> matches <see cref="hostName"/>
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="hostName"></param>
        /// <returns></returns>
        public static bool Check(string ip, string hostName)
        {
            return ResultCache.GetOrAdd(new CheckInfo(ip, hostName), Recheck);
        }

        private static bool Recheck(CheckInfo checkInfo)
        {
            try
            {
                var ipAddress = IPAddress.Parse(checkInfo.IP);
                var hostEntry = Dns.GetHostEntry(ipAddress);
                if (!hostEntry.AddressList.Contains(ipAddress))
                {
                    return false;
                }
                return hostEntry.Aliases.Concat(hostEntry.HostName).Count(i => i.ToLowerInvariant().Contains(checkInfo.HostName.ToLowerInvariant())) != 0;
            }
            catch
            {
                return false;
            }
        }

        struct CheckInfo
        {
            private readonly string _ip;
            private readonly string _hostName;

            public string IP
            {
                get { return _ip; }
            }

            public string HostName
            {
                get { return _hostName; }
            }

            public CheckInfo(string ip, string hostName)
            {
                _ip = ip;
                _hostName = hostName;
            }
        }
    }
}
